package com.nekonomics
package persistence.repository


import domain.entity.User
import types.UserRole
import utils.magic.TypeMagic
import utils.{SqlUtil, traced}

import doobie.*
import doobie.hikari.HikariTransactor
import doobie.implicits.*
//import doobie.util.log.*
//import doobie.postgres._
import doobie.postgres.implicits.*
//import doobie.postgres.pgisimplicits._
import zio.*
import zio.interop.catz.*

trait UserRepo {
  def findByEmail(email: String): ConnectionIO[Option[User]]

  def findById(id: Long): ConnectionIO[Option[User]]

  def insert(email: String, passwordHash: String, nickname: String, role: UserRole): ConnectionIO[Long]
}


object UserRepo {
  val live: ULayer[UserRepo] = ZLayer.succeed(new UserRepoLive)

}


class UserRepoLive extends UserRepo {

  override def findByEmail(email: String): ConnectionIO[Option[User]] = {
    SqlUtil.selectFromWhereOpt[User](cond = Some(fr"email = $email"))
      .query[User]
      .option
  }


  override def findById(id: Long): ConnectionIO[Option[User]] = {
    SqlUtil.selectFromWhereOpt[User](cond = Some(fr"id = $id"))
      .query[User]
      .option
  }


  override def insert(email: String, passwordHash: String, nickname: String, role: UserRole): ConnectionIO[Long] = {
    sql"""
         |insert into 
         |public.user 
         |(email, nickname, password_hash, role) 
         |values ($email, $nickname, $passwordHash, $role)
         |""".stripMargin
      .update
      .withUniqueGeneratedKeys[Long]("id")
  }

}



























